﻿// Sheego.Service.X400
// Copyright(C) 2015 Schwab Versand GmbH
//
// This source file is subject to the Microsoft Public License(Ms-PL).
// http://www.opensource.org/licenses/ms-pl.html
// All other rights reserved.
using Sheego.Service.X400.Job.Shared;
using Sheego.Service.X400.Job.Shared.BO;
using Sheego.Service.X400.Job.Shared.Locator;
using Sheego.Service.X400.Job.Shared.Parser;
using Sheego.Service.X400.Scheduler.Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sheego.Service.X400.Job.Impl
{
    class X400Job : IJob
    {
        IJobLogger Logger;

        private IUAFICommandFactory CommandFactory;
        private IJobConfiguration JobConfiguration;
        private IFileManager FileManager;
        private IMailManager MailManager;
        private IX400MessageParser MessageParser;
        private IX400MessageRouter MessageRouter;
        private IX400MessageCache MessageCache;

        public X400Job(IJobLogger logger, IUAFICommandFactory commandFactory,
            IJobConfiguration jobConfiguration,
            IFileManager fileManager, IMailManager mailManager,
            IX400MessageParser messageParser, IX400MessageRouter messageRouter,
            IX400MessageCache messageCache)
        {
            Logger = logger;
            CommandFactory = commandFactory;
            JobConfiguration = jobConfiguration;
            FileManager = fileManager;
            MailManager = mailManager;
            MessageParser = messageParser;
            MessageRouter = messageRouter;
            MessageCache = messageCache;
        }
        #region IJob Members

        public String Name
        {
            get
            {
                return "X.400";
            }
        }
        public bool Disabled { get; set; }

        public bool Match(int hour, int min)
        {
            if (hour < 0 || 23 < hour)
                throw new ArgumentOutOfRangeException("hour");
            if (min < 0 || 59 < min)
                throw new ArgumentOutOfRangeException("min");

           return (JobConfiguration.Hour.Values.Contains(hour) &&
                JobConfiguration.Minute.Values.Contains(min));
        }

        public int Exec()
        {

            //UAFI-Kommando aufrufen
            var Process = JobLocator.GetProcess();

            var FetchAllCommand = CommandFactory.CreateFetchAllCommand();
            var Response = Process.Call(FetchAllCommand);

            if (!Response.Success)
            {
                Logger.Error("Error while Call Command {0}", Response.StatusText);

                //Send Error Message
                var Mail = JobLocator.GetMailMessage();
                Mail.SubjectType = "Error";
                Mail.SubjectDetail = "Process.Call";
                Mail.Recipients.Add(JobConfiguration.ErrorRecipient);
                Mail.Body = Response.StatusText;
                MailManager.Send(Mail);

                return -1; 
            }

            //Messages Verarbeiten


            foreach (var MessageId in Response.Messages)
            {
                try
                {
                    //Message Parsen
                    var FileNameList = FileManager.ListFileNamesForMessageId(MessageId);
                    var Message = MessageParser.Parse(FileNameList);

                    //Message schon mal verarbeitet?
                    if (MessageCache.Contains(Message))
                        continue;

                    //Nur einmal verarbeiten
                    MessageCache.Add(Message);

                    //Message Routen
                    MessageRouter.Route(Message);
                    Logger.Info("Message from \"{0}\" processed ", Message.P2Originator);

                }
                catch (Exception processMessageException)
                {
                    Logger.Error("Error while process message {0} : {1}", MessageId, processMessageException);
                    
                    var Mail = JobLocator.GetMailMessage();
                    Mail.SubjectType = "Error";
                    Mail.SubjectDetail = "MessageProcessing";
                    Mail.Recipients.Add(JobConfiguration.ErrorRecipient);
                    Mail.Body = processMessageException.ToString();
                    MailManager.Send(Mail);
                }

            }

            return 0;
        }

        #endregion

    }
}
